/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package apus.persistence.jdbc;

import apus.entity.Period;
import apus.entity.RealPeriod;
import apus.exception.DatabaseException;
import apus.exception.EntityNotFoundException;
import apus.persistence.PeriodDAO;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author  Roman Dyatkovsky
 * @author  Maxim Vasilevsky
 * @since APUS v0.5
 */
public class JdbcPeriodDAO extends AbstractJdbcDAO<Period> implements PeriodDAO{

    @Override
    public void create(Period entity) {
        entity.setId(getNextId());
        
        Connection cn = getConnection();
        PreparedStatement st = null;
        
        try {
             st = cn.prepareStatement("insert into TIME_PERIOD"
                                    + " (ID_PERIOD, DATE_START, DATE_END) values (?,?,?)");
             st.setInt(1,entity.getId());
             st.setDate(2, new java.sql.Date(entity.getStartDate().getTime()));
             st.setDate(3, new java.sql.Date(entity.getEndDate().getTime()));
             st.execute();
        } catch (SQLException ex) {
            throw new DatabaseException("Can't create new period!", ex);
        } finally {
            try {
                st.close();
            } catch (SQLException ex) {
                System.err.println("Can't close statement");
                ex.printStackTrace(System.err);
            }
        }
    }

    @Override
    public Period read(int id) {
        Connection cn = getConnection();
        Statement st = null;
        ResultSet rs = null;
        Period period = null;
        try {
            st = cn.createStatement();
            rs = st.executeQuery("select * from TIME_PERIOD where ID_PERIOD = "+id);
            if (rs.next()) {
                    period = new RealPeriod(new java.util.Date(rs.getDate("DATE_START").getTime()), 
                            new java.util.Date(rs.getDate("DATE_END").getTime()));
                    period.setId(rs.getInt("ID_PERIOD"));
            }
        } catch (SQLException ex) {
            throw new DatabaseException("Can't read period with id="+id, ex);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (st != null) {
                    st.close();
                }
            } catch (SQLException ex) {
                System.err.println("Can't close statement");
                ex.printStackTrace(System.err);
            }
        }
        if (period==null) {
            throw new EntityNotFoundException("Period with id = "+ id + " not found");
        }
        return period;
    }

    
    @Override
    public void update(Period entity) {
        Connection cn = getConnection();
        PreparedStatement st = null;
        try {
            st = cn.prepareStatement("update TIME_PERIOD set DATE_START=?, DATE_START=? "
                                    + "where ID_PERIOD=?");
            st.setDate(1, new java.sql.Date(entity.getStartDate().getTime()));
            st.setDate(2, new java.sql.Date(entity.getEndDate().getTime()));
            st.setInt(3, entity.getId());
            st.execute();     
        } catch (SQLException e) {
            throw new DatabaseException("Can't update period with ID=" + entity.getId(), e);
        } finally {
            try {
                st.close();
            } catch (SQLException ex) {
                System.err.println("Can't close statement");
                ex.printStackTrace(System.err);
            }
        }
    }

    @Override
    public void delete(Period entity) {
        Connection cn = getConnection();
        PreparedStatement st = null;
        try {
            st = cn.prepareStatement("delete from TIME_PERIOD where ID_PERIOD=?");
            st.setInt(1, entity.getId());
            st.execute();
        } catch (SQLException e) {
            throw new DatabaseException("Can't delete period with ID=" + entity.getId(), e);
        } finally {
            try {
                st.close();
            } catch (SQLException ex) {
                System.err.println("Can't close statement");
                ex.printStackTrace(System.err);
            }
        }
    }

    
    @Override
    public List<Period> findAll() {
        Connection cn = getConnection();
        Statement st = null;
        ResultSet rs = null;
        List<Period> periodList = new ArrayList<>();
        try {
            st = cn.createStatement();
            rs = st.executeQuery("select * from TIME_PERIOD");
            Period period;
            while (rs.next()) {
                    period = new RealPeriod(new java.util.Date(rs.getDate("DATE_START").getTime()), 
                            new java.util.Date(rs.getDate("DATE_END").getTime()));
                    period.setId(rs.getInt("ID_PERIOD"));
                    periodList.add(period);
            }
        } catch (SQLException ex) {
            throw new DatabaseException("Can't read period list", ex);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (st != null) {
                    st.close();
                }
            } catch (SQLException ex) {
                System.err.println("Can't close statement");
                ex.printStackTrace(System.err);
            }
        }
        if (periodList.isEmpty()) {
            throw new EntityNotFoundException("Periods not found");
        }
        return periodList;
    }

    
    
    @Override
    public Period readByStartAndEndDates(Date start, Date end) {
        Connection cn = getConnection();
        PreparedStatement st = null;
        ResultSet rs = null;
        Period period = null;
        try {
            st = cn.prepareStatement("select ID_PERIOD, DATE_START, DATE_END"
                          + " from TIME_PERIOD where DATE_START=? and DATE_END=?");
            st.setDate(1, new java.sql.Date(start.getTime()));
            st.setDate(2, new java.sql.Date(end.getTime()));
            rs = st.executeQuery();
            if (rs.next()) {
                    period = new RealPeriod(new java.util.Date(rs.getDate("DATE_START").getTime()),
                            new java.util.Date(rs.getDate("DATE_END").getTime()));
                    period.setId(rs.getInt("ID_PERIOD"));
            }
        } catch (SQLException ex) {
            throw new DatabaseException("Can't read period.", ex);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (st != null) {
                    st.close();
                }
            } catch (SQLException ex) {
                System.err.println("Can't close statement.");
                ex.printStackTrace(System.err);
            }
        }
        if (period==null) {
            throw new EntityNotFoundException("Period not found.");
        }
        return period;
    }
    
}
